package item

import (
	"context"
	"encoding/json"
	"fmt"
	"github.com/gogf/gf/v2/os/gctx"
	"github.com/gogf/gf/v2/os/glog"
	"github.com/gogf/gf/v2/os/gmlock"
	"xr-game-server/core/constants/common"
	"xr-game-server/core/event"
	"xr-game-server/core/httpserver"
	"xr-game-server/dto/itemdto"
	"xr-game-server/gamecfg"
	"xr-game-server/gameevent"
	"xr-game-server/module/protocol"
)

func AddItem(context context.Context, req *itemdto.AddItemReq) (res bool, er error) {
	add(httpserver.GetAuthId(context), req.Data, true)
	return true, nil
}

func getLockStr(roleId uint64) string {
	return fmt.Sprintf("item_%v", roleId)
}

func onAddItemEvent(msg any) {
	ctx := gctx.New()
	if msg == nil {
		glog.Errorf(ctx, "add itemdto error null 加物品")
		return
	}
	eventData := msg.(*gameevent.AddItemStrData)
	if eventData.RoleId == common.Zero {
		glog.Errorf(ctx, "add itemdto error null 加物品 角色id为0")
		return
	}
	if eventData.ItemStr == "" {
		glog.Errorf(ctx, "add itemdto error null 加物品 角色id=%v,itemstr为空", eventData.RoleId)
		return
	}
	var items [][]uint64
	err := json.Unmarshal([]byte(eventData.ItemStr), &items)
	if err != nil {
		glog.Errorf(ctx, "add itemdto error 加物品 角色id=%v,itemstr=%v", eventData.RoleId, eventData.ItemStr)
		return
	}
	add(eventData.RoleId, items, eventData.Push)
}

func onAddItemArray(msg any) {
	itemArrayEvent := msg.(*gameevent.AddItemArrayEvent)
	add(itemArrayEvent.RoleId, itemArrayEvent.Items, itemArrayEvent.Push)
}

// Add 添加物品 发金币,道具
func add(roleId uint64, items [][]uint64, canPush bool) {
	itemLock := getLockStr(roleId)
	gmlock.Lock(itemLock)
	defer gmlock.Unlock(itemLock)
	if len(items) == common.Zero {
		return
	}
	ctx := gctx.New()
	itemModels := protocol.NewItemModels(items)
	typeMap := make(map[uint32][]*protocol.ItemModel)
	//检查是否满足数量
	for _, item := range itemModels {
		itemCfg := gamecfg.GetItemById(item.Id)
		if itemCfg == nil {
			glog.Infof(ctx, "角色id=%v,itemid=%v not found", roleId, item.Id)
			return
		}
		handler := protocol.GetItemHandlerBy(itemCfg.ItemHandler)
		if handler == nil {
			glog.Infof(ctx, "角色id=%v,处理器错误=%v not found", roleId, itemCfg.ItemHandler)
			return
		}
		typeModels, ok := typeMap[itemCfg.ItemHandler]
		if !ok {
			typeModels = make([]*protocol.ItemModel, common.Zero)
			typeMap[itemCfg.ItemHandler] = typeModels
		}
		typeModels = append(typeModels, item)
		typeMap[itemCfg.ItemHandler] = typeModels
	}
	for key, val := range typeMap {
		handler := protocol.GetItemHandlerBy(key)
		handler.AddItem(roleId, val, canPush)
	}
	//检查失败,发送邮件
	mailItems := make([]*protocol.ItemModel, common.Zero)
	for _, item := range itemModels {
		if item.Fail > common.Zero {
			mailItems = append(mailItems, protocol.NewMailItem(item.Id, item.Fail))
		}
	}
	if len(mailItems) > common.Zero {
		event.Pub(gameevent.MailEvent, gameevent.NewMailEvent(roleId, mailItems, 0))
	}
	//发送物品日志
	event.Pub(gameevent.ItemChange, gameevent.NewItemChangeData(roleId, itemModels))
}
